package pl.puntin.punclient.view;

import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import pl.puntin.punclient.controller.Controller;
import pl.puntin.punclient.messages.ImageMessage;
import pl.puntin.punclient.messages.RoomListMessage;
import pl.puntin.punclient.view.game.GameView;


/*
 * Klasa ktora bedzie zarzadzala widokami
 * 
 * LUKASZ CZYTAJ TO !!!!!!!!!!!!!!!!!!!!!!!!!
 * ta klasa komunikuje sie WYLACZNIE  z controlerem
 * pamietaj aby Controller wolal metody tej klasy a nie np loginView
 * 
 * w aplikacji jest tylko jeden JFrame !
 * reszta widokow to JPanel
 */
public final class View
{
	private final JFrame applicationWindow;
	private final Controller controller;
	private GameView gameView;
	private final LoginView2 loginView;
	private final RoomView roomView;
	private JPanel currentView;
	public String login;
	private boolean youAreDrawer = false;

	//TODO nie da sie wyslac wiadomosci chatowej enterem
	//TODO haslo nie czysci
	//TODO czas sie nie zeruje
	//TODO podczas logowanie nie da sie zalogowac enterem
	//TODO wyczyscic czat po zmianie pokoju itp
	//TODO uwazaj na watki ! odpalaj tylko przez invoke later
	//TODO jak ktos zganie to tez trzeba jakos zrestowac game view, liczniki itp.
	//TODO blokada obrazka gdy gra sie nie zaczela
	//TODO obsluga start game false
	//TODO obsluga end of round
	
	public View(final Controller controller)
	{
		this.controller = controller;
		
		applicationWindow = new JFrame("Gra");
		
		loginView = new LoginView2(controller);
		roomView = new RoomView(controller);
		gameView = new GameView(controller);
		setLoginView();
		
		applicationWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		applicationWindow.setLocationByPlatform(true);
		applicationWindow.pack();
		applicationWindow.setVisible(true);
	}
	
	public void setLoginView()
	{
		currentView = loginView;
		applicationWindow.setContentPane(loginView);
		applicationWindow.pack();
	}
	
	public void changeToRoomView()
	{
		restartGameView();
		currentView = roomView;
		applicationWindow.setContentPane(roomView);
		applicationWindow.pack();
	}
	
	public void changeToGameView()
	{
		currentView = gameView;
		applicationWindow.setContentPane(gameView);
		applicationWindow.pack();
	}
	
	public void popUpMessage(final String s)
	{
		
		JOptionPane.showMessageDialog(applicationWindow, s);
	}

	public void popErrorMessage(final String message)
	{
		JOptionPane.showMessageDialog(applicationWindow, message, "Blad", JOptionPane.ERROR_MESSAGE);
//		SwingUtilities.invokeLater(new Runnable()
//		{
//			@Override
//			public void run() {
//			}
//		});
	}
	
	public void errorMessage(final String message)
	{
		Date date = new Date();
		System.err.format("[%d:%02d:%02d]%s%n", date.getHours(), date.getMinutes(), date.getSeconds(), message);
	}
	
	public void logMessage(final String message)
	{
		Date date = new Date();
		System.out.format("[%d:%02d:%02d]%s%n", date.getHours(), date.getMinutes(), date.getSeconds(), message);
	}
	
	public void tryToLogAgain()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				errorMessage("Login jest już zajęty. Wpisz nowy login ponownie.");
				loginView.getNewLogin();
			}
		});
	}
	
	public void chatMessage(final String message)
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				if(currentView != gameView)
					popErrorMessage("Łooo majn god, co się dzije");
				else
					gameView.showChatMessasge(message);
			}
		});
	}
	
	/**
	 * Ustawia gameView w tryb rysujacego
	 */
	public void youAreDrawer(final String s)
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run()
			{
				logMessage("Rysownikiem jestes i powinno wszystko dzialac!A jak nie dziala to to kurwa jest pojebane!!!");
				gameView.roundEnd();
				gameView.beginRound();
				gameView.youAreDrowing(s);
				gameView.startSendingImage();
			}
		});
	}
	
	public void displayImageMessage(final ImageMessage message)
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				if(currentView != gameView)
					changeToGameView();
				
				gameView.displayImage(message.getBufferedImage());
			}
		});
	}
	
	public void joinExistingGame(final String s)
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				changeToGameView();
				applicationWindow.setTitle(s);	
			}
		});
	}
	public void youAreNotInRoomView()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				changeToRoomView();
			}
		});
	}
	public void displayRoomList(final RoomListMessage message)
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				roomView.setList(message.roomList , message.roomPlayers);						
			}
		});
	}

	public void tryingToConnect()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				//TODO laczenie w login view ...
				loginView.loginButton.setText("Trwa laczenie ...");
			}
		});
	}

	public void reLogin()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				if(currentView != loginView)
					setLoginView();
				
				loginView.loginButton.setEnabled(true);
				loginView.loginButton.setText("Zaloguj");
			}
		});
		
	}

	public void lockLoginView()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				loginView.loginButton.setEnabled(false);
			}
		});
		
	}
	
	public void beginGame()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				gameView.beginRound();
				gameView.gameStarted();
			}
		});
	}
/*	
	public void beginNextRoundDrawerPass()
	{
		gameView.showChatMessasge("Rysujący jest słaby i się poddał.\n");
		gameView.beginRound();
	}
	
	public void beginNextRoundSomebodyWinned(String login)
	{
		if(this.login.equals(login))
			gameView.showChatMessasge("Jestes niesamowitym mistrzem i udało Ci się zagdnąć.\n");
		else
			gameView.showChatMessasge(login+" jest mistrzem udało mu się zagdnąć.\n");
		gameView.beginRound();

	}
	
	public void drawerLeftTheGame()
	{
		gameView.showChatMessasge("Rysujący opuścił grę.\nRozpoczynamy nową rundę.\n");
		gameView.beginRound();
	}
	
	public void tiomeOut()
	{
		gameView.showChatMessasge("Koniec czasu.\nRozpoczynamy nową rundę\n");
		gameView.beginRound();
	}
	*/
	public void newRound()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				logMessage("nowa runda");
				gameView.roundEnd();
				gameView.beginRound();
			}
		});
	}
	
	public void endOfGame()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				gameView.gameEnds();
			}
		});
	}

	public void updateRanking(final String[] names, final String[] points)
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				gameView.setRanking(names, points);
			}
		});

	}


	public void gameAlreadyBegined() {
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				gameView.gameStarted();
				gameView.youCantGetTime();
			}
		});
		
	}

	public void restartGameView() {
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				gameView = new GameView(controller);
			}
		});
	}
	
	public void youAreNotDrawer()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				youAreDrawer = false;
			}
		});
	}
	
	public void youAreDrawerr()
	{
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				youAreDrawer = true;
			}
		});
	}
	public boolean getDrawer()
	{
		return youAreDrawer;
	}
}
